package com.fbs.wowo.finance.util;

import com.fbs.wowo.exception.GivenNullParamException;
import com.fbs.wowo.util.common.Generator;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class BillGenerator {
    // TODO 抽成
    public static final BigDecimal Percentage = new BigDecimal("0.8");

    // 交易状态
    public static final byte StatusSuccess = 1; // 成功
    public static final byte StatusRefund = 2;  // 退款
    public static final byte StatusWait = 3;    // 未发放
    public static final byte StatusOrder = 4;   // 下单 未支付

    // 场景
    public static final String SceneTransferTo = "转账-来自";
    public static final String SceneTransferFrom = "转账-给";
    public static final String SceneRedTo = "红包-来自";
    public static final String SceneRedFrom = "红包-给";
    public static final String SceneReg = "注册奖励";
    public static final String SceneInvited = "填写邀请注册奖励";
    public static final String SceneInvite = "邀请他人注册奖励";
    public static final String SceneBuyArticle = "图文 - 购买";
    public static final String SceneBuyAudio = "音频 - 购买";
    public static final String SceneBuyAlbum = "专辑 - 购买";
    public static final String SceneBuyLive = "直播 - 购买";
    public static final String SceneSellArticle = "图文 - 售出";
    public static final String SceneSellAudio = "音频 - 售出";
    public static final String SceneSellAlbum = "专辑 - 售出";
    public static final String SceneSellLive = "直播 - 售出";
    public static final String SceneBuy = "购买";
    public static final String SceneSell = "售出";
    public static final String ScenePayReward = "打赏";
    public static final String ScenePayRewarded = "收到打赏";

    // 收入还是支出
    public static final byte Income_Income = 1;
    public static final byte Income_Outcome = 2;

    // 打赏 or other
    public static final byte Pro_Reward = 1;
    public static final byte Pro_Article = 2;

    // 访问渠道
    public static final byte AccessNo = 0;
    public static final byte AccessPhone = 1;   // 手机访问
    public static final byte AccessWeb = 2;     // pc访问

    // 支付方式
    public static final byte PayNo        = 1;
    public static final byte PayOri       = 2;
    public static final byte PayWXNative  = 3;
    public static final byte PayWXApp     = 4;
    public static final byte PayAli       = 5;
    public enum TradeType {
        PayNo((byte) 1, "NO"),              //
        PayOri((byte) 2, "ORIGIN"),         // 原生
        PayWXNative((byte) 3, "NATIVE"),    // 微信扫码
        PayWXApp((byte) 4, "APP"),          // 微信app支付
        PayAli((byte) 5, "ALI"),            // 阿里
        PayWXCash((byte) 6, "WXC")          // 微信提现
        ;

        private final byte key;
        private final String value;

        TradeType(byte key, String value) {
            this.key = key;
            this.value = value;
        }

        public static String getValue(byte key) {
            for (TradeType c : TradeType.values()) {
                if (c.getKey() == key) {
                    return c.value;
                }
            }
            return null;
        }
        public static Byte getKey(String value) {
            for (TradeType c : TradeType.values()) {
                if (c.getValue().equals(value)) {
                    return c.key;
                }
            }
            return null;
        }

        public byte getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }

    // 账单类型
    public static final byte Article = 1;       // 文章 图文
    public static final byte Audio = 2;         // 音频
    public static final byte Album = 3;         // 专辑
    public static final byte Live = 4;          // 直播
    public static final byte WXCash = 5;        // 微信提现
    public enum ProCt {
        ARTICLE((byte) 1, "图文"),    // 文章 图文
        AUDIO((byte) 2, "音频"),      // 音频
        ALBUM((byte) 3, "专辑"),      // 专辑
        LIVE((byte) 4, "直播"),       // 直播
        WXCASH((byte) 5, "微信提现");     // 直播

        private final byte key;
        private final String value;

        ProCt(byte key, String value) {
            this.key = key;
            this.value = value;
        }

        public static String getValue(byte key) {
            for (ProCt c : ProCt.values()) {
                if (c.getKey() == key) {
                    return c.value;
                }
            }
            return null;
        }

        public byte getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }
    // 商品类型
    public enum ProT {
        REWARD((byte) 1, "打赏"),     // 赏
        BUY((byte) 2, "购买"),        // 购买浏览权限
        CASH((byte) 3, "提现"),       // 提现
        ;

        private final byte key;
        private final String value;

        ProT(byte key, String value) {
            this.key = key;
            this.value = value;
        }

        public static String getValue(byte key) {
            for (ProT c : ProT.values()) {
                if (c.getKey() == key) {
                    return c.value;
                }
            }
            return null;
        }

        public byte getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }
    }

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

    /**
     * 生成场景字符串
     * @param productName   产品名
     * @param productType   产品类型
     * @param productCategory        打赏或购买
     * @param isIncome      收入 或 支出
     * @return              场景字符串
     */
    public static String genScene(String productName, Byte productType, Byte productCategory, Byte isIncome) {
        StringBuilder sb = new StringBuilder();
        // 支出或收入
        if (isIncome == BillGenerator.Income_Income) {
            sb.append("收入-");
        } else {
            sb.append("支出-");
        }
        // 打赏还是购买
        sb.append(ProT.getValue(productType) + "-");
        // 类型
        sb.append(ProCt.getValue(productCategory) + "-");
        // 产品名
        sb.append(productName);
        return sb.toString();
    }

    /**
     * 交易单号生成
     * @param accessType 访问方式（web，手机）
     * @param tradeType   支付方式（微信，支付宝）
     * @param productCategory 交易类型（转账，红包，充值，彩蛋）
     * @return 单号
     */
    public static final String tradeId(Byte accessType, Byte tradeType, Byte productCategory, Byte productType) {
        DecimalFormat decimalFormat = new DecimalFormat("00");
        String accessTypeStr = decimalFormat.format(accessType);
        String tradeTypeStr = decimalFormat.format(tradeType);
        String productCategoryStr = decimalFormat.format(productCategory);
        String productTypeStr = decimalFormat.format(productType);
        validateStr(accessTypeStr);
        validateStr(tradeTypeStr);
        validateStr(productCategoryStr);
        validateStr(productTypeStr);
        String key = productCategoryStr + productTypeStr + tradeTypeStr + sdf.format(new Date()) + accessTypeStr + Generator.randomNum(4);
        return key;
    }

    private static void validateStr(String str) throws GivenNullParamException {
        if (!StringUtils.hasText(str)) throw new GivenNullParamException();
    }
}
